package BlockingQueue;

//模拟实现BlockingQueue

public class Demo1 {
    static class BlockingQueue{
        //用数组实现的循环队列
        private int[]elem=new int[4];
        private int head=0;
        private int tail=0;
        //有效元素个数
        private int useSize=0;
        //锁对象----保证线程安全的
        private Object locker=new Object();

        //添加元素
        public void put(int i) throws InterruptedException {
            synchronized (locker){
                //虽然notify每次只随机唤醒一个线程，但写个循环还是比较保险
                while(this.useSize==this.elem.length){
                    //满了，线程阻塞等待wait
                    locker.wait();
                }

                elem[tail]=i;
                useSize++;
                tail=(tail+1)% elem.length;
                locker.notify();
            }
        }

        //弹出队头元素
        public int take() throws InterruptedException {
            synchronized (locker){
                //虽然notify每次只随机唤醒一个线程，但写个循环还是比较保险
                while(this.useSize==0){
                    //没有元素,线程阻塞等待
                    locker.wait();
                }

                int top=elem[head];
                head=(head+1)% elem.length;
                useSize--;
                locker.notify();
                return top;

            }

        }

    }

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue blockingQueue=new BlockingQueue();
        //客户1线程
        Thread custom1=new Thread(()->{
            while(true){
                try {
                    int top=blockingQueue.take();
                    System.out.println("客户1拿到:"+top);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //客户2线程
        Thread custom2=new Thread(()->{
            while(true){
                try {
                    int top=blockingQueue.take();
                    System.out.println("客户2拿到:"+top);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //生产的厂家线程
        Thread factory =new Thread(()->{
            while(true){
                for(int i=1;i<=9999999;i++){
                    try {
                        System.out.println("厂家生产："+i);
                        blockingQueue.put(i);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }

        });
        custom1.start();
        custom2.start();
        factory.start();

        custom1.join();
        custom2.join();
        factory.join();
    }


}
